Proxy out to _gtk_tree_row_reference_deleted. (inserted_callback): Proxy
authorJonathan Blandford <jrb@redhat.com>
Wed, 28 Feb 2001 00:35:25 +0000 (00:35 +0000)
committerJonathan Blandford <jrb@src.gnome.org>
Wed, 28 Feb 2001 00:35:25 +0000 (00:35 +0000)
Tue Feb 27 19:32:53 2001  Jonathan Blandford  <jrb@redhat.com>

* gtk/gtktreemodel.c (deleted_callback): Proxy out to
_gtk_tree_row_reference_deleted.
(inserted_callback): Proxy out to
_gtk_tree_row_reference_inserted.
(_gtk_tree_row_reference_new_from_view): Somewhat yukky hack to
get around signal emission ordering problem.

* gtk/gtktreeselection.c (gtk_tree_selection_real_unselect_all):
fix to work with SINGLE
(_gtk_tree_selection_internal_select_node): Major sanitization on
selections.  SINGLE now seems to work.

* tests/Makefile.am: add testtreecolumn.c:

* tests/testtreecolumn.c: New test.  Mostly points out selection
bugs currently, but will test columns later.

* gtk/gtkrbtree.c (_gtk_rbtree_remove_node): Fix really nasty
selection bug.  I hate touching this code -- it's scary.

18 files changed:
ChangeLog
ChangeLog.pre-2-0
ChangeLog.pre-2-10
ChangeLog.pre-2-2
ChangeLog.pre-2-4
ChangeLog.pre-2-6
ChangeLog.pre-2-8
gtk/gtkcellrenderertext.c
gtk/gtkliststore.c
gtk/gtkrbtree.c
gtk/gtkrbtree.h
gtk/gtktreemodel.c
gtk/gtktreeprivate.h
gtk/gtktreeselection.c
gtk/gtktreeselection.h
gtk/gtktreeview.c
tests/Makefile.am
tests/testtreecolumns.c [new file with mode: 0644]

index 749c20c2d9d677b5c513e6f4621ccd9c30498cb3..fc423e44928deabda23311b83c54947b7c8ecbcf 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,25 @@
+Tue Feb 27 19:32:53 2001  Jonathan Blandford  <jrb@redhat.com>
+
+       * gtk/gtktreemodel.c (deleted_callback): Proxy out to
+       _gtk_tree_row_reference_deleted.
+       (inserted_callback): Proxy out to
+       _gtk_tree_row_reference_inserted.
+       (_gtk_tree_row_reference_new_from_view): Somewhat yukky hack to
+       get around signal emission ordering problem.
+
+       * gtk/gtktreeselection.c (gtk_tree_selection_real_unselect_all):
+       fix to work with SINGLE 
+       (_gtk_tree_selection_internal_select_node): Major sanitization on
+       selections.  SINGLE now seems to work.
+
+       * tests/Makefile.am: add testtreecolumn.c:
+
+       * tests/testtreecolumn.c: New test.  Mostly points out selection
+       bugs currently, but will test columns later.
+
+       * gtk/gtkrbtree.c (_gtk_rbtree_remove_node): Fix really nasty
+       selection bug.  I hate touching this code -- it's scary.
+
 2001-02-26  Havoc Pennington  <hp@redhat.com>
 
        * gtk/testgtk.c: test the window state stuff
index 749c20c2d9d677b5c513e6f4621ccd9c30498cb3..fc423e44928deabda23311b83c54947b7c8ecbcf 100644 (file)
@@ -1,3 +1,25 @@
+Tue Feb 27 19:32:53 2001  Jonathan Blandford  <jrb@redhat.com>
+
+       * gtk/gtktreemodel.c (deleted_callback): Proxy out to
+       _gtk_tree_row_reference_deleted.
+       (inserted_callback): Proxy out to
+       _gtk_tree_row_reference_inserted.
+       (_gtk_tree_row_reference_new_from_view): Somewhat yukky hack to
+       get around signal emission ordering problem.
+
+       * gtk/gtktreeselection.c (gtk_tree_selection_real_unselect_all):
+       fix to work with SINGLE 
+       (_gtk_tree_selection_internal_select_node): Major sanitization on
+       selections.  SINGLE now seems to work.
+
+       * tests/Makefile.am: add testtreecolumn.c:
+
+       * tests/testtreecolumn.c: New test.  Mostly points out selection
+       bugs currently, but will test columns later.
+
+       * gtk/gtkrbtree.c (_gtk_rbtree_remove_node): Fix really nasty
+       selection bug.  I hate touching this code -- it's scary.
+
 2001-02-26  Havoc Pennington  <hp@redhat.com>
 
        * gtk/testgtk.c: test the window state stuff
index 749c20c2d9d677b5c513e6f4621ccd9c30498cb3..fc423e44928deabda23311b83c54947b7c8ecbcf 100644 (file)
@@ -1,3 +1,25 @@
+Tue Feb 27 19:32:53 2001  Jonathan Blandford  <jrb@redhat.com>
+
+       * gtk/gtktreemodel.c (deleted_callback): Proxy out to
+       _gtk_tree_row_reference_deleted.
+       (inserted_callback): Proxy out to
+       _gtk_tree_row_reference_inserted.
+       (_gtk_tree_row_reference_new_from_view): Somewhat yukky hack to
+       get around signal emission ordering problem.
+
+       * gtk/gtktreeselection.c (gtk_tree_selection_real_unselect_all):
+       fix to work with SINGLE 
+       (_gtk_tree_selection_internal_select_node): Major sanitization on
+       selections.  SINGLE now seems to work.
+
+       * tests/Makefile.am: add testtreecolumn.c:
+
+       * tests/testtreecolumn.c: New test.  Mostly points out selection
+       bugs currently, but will test columns later.
+
+       * gtk/gtkrbtree.c (_gtk_rbtree_remove_node): Fix really nasty
+       selection bug.  I hate touching this code -- it's scary.
+
 2001-02-26  Havoc Pennington  <hp@redhat.com>
 
        * gtk/testgtk.c: test the window state stuff
index 749c20c2d9d677b5c513e6f4621ccd9c30498cb3..fc423e44928deabda23311b83c54947b7c8ecbcf 100644 (file)
@@ -1,3 +1,25 @@
+Tue Feb 27 19:32:53 2001  Jonathan Blandford  <jrb@redhat.com>
+
+       * gtk/gtktreemodel.c (deleted_callback): Proxy out to
+       _gtk_tree_row_reference_deleted.
+       (inserted_callback): Proxy out to
+       _gtk_tree_row_reference_inserted.
+       (_gtk_tree_row_reference_new_from_view): Somewhat yukky hack to
+       get around signal emission ordering problem.
+
+       * gtk/gtktreeselection.c (gtk_tree_selection_real_unselect_all):
+       fix to work with SINGLE 
+       (_gtk_tree_selection_internal_select_node): Major sanitization on
+       selections.  SINGLE now seems to work.
+
+       * tests/Makefile.am: add testtreecolumn.c:
+
+       * tests/testtreecolumn.c: New test.  Mostly points out selection
+       bugs currently, but will test columns later.
+
+       * gtk/gtkrbtree.c (_gtk_rbtree_remove_node): Fix really nasty
+       selection bug.  I hate touching this code -- it's scary.
+
 2001-02-26  Havoc Pennington  <hp@redhat.com>
 
        * gtk/testgtk.c: test the window state stuff
index 749c20c2d9d677b5c513e6f4621ccd9c30498cb3..fc423e44928deabda23311b83c54947b7c8ecbcf 100644 (file)
@@ -1,3 +1,25 @@
+Tue Feb 27 19:32:53 2001  Jonathan Blandford  <jrb@redhat.com>
+
+       * gtk/gtktreemodel.c (deleted_callback): Proxy out to
+       _gtk_tree_row_reference_deleted.
+       (inserted_callback): Proxy out to
+       _gtk_tree_row_reference_inserted.
+       (_gtk_tree_row_reference_new_from_view): Somewhat yukky hack to
+       get around signal emission ordering problem.
+
+       * gtk/gtktreeselection.c (gtk_tree_selection_real_unselect_all):
+       fix to work with SINGLE 
+       (_gtk_tree_selection_internal_select_node): Major sanitization on
+       selections.  SINGLE now seems to work.
+
+       * tests/Makefile.am: add testtreecolumn.c:
+
+       * tests/testtreecolumn.c: New test.  Mostly points out selection
+       bugs currently, but will test columns later.
+
+       * gtk/gtkrbtree.c (_gtk_rbtree_remove_node): Fix really nasty
+       selection bug.  I hate touching this code -- it's scary.
+
 2001-02-26  Havoc Pennington  <hp@redhat.com>
 
        * gtk/testgtk.c: test the window state stuff
index 749c20c2d9d677b5c513e6f4621ccd9c30498cb3..fc423e44928deabda23311b83c54947b7c8ecbcf 100644 (file)
@@ -1,3 +1,25 @@
+Tue Feb 27 19:32:53 2001  Jonathan Blandford  <jrb@redhat.com>
+
+       * gtk/gtktreemodel.c (deleted_callback): Proxy out to
+       _gtk_tree_row_reference_deleted.
+       (inserted_callback): Proxy out to
+       _gtk_tree_row_reference_inserted.
+       (_gtk_tree_row_reference_new_from_view): Somewhat yukky hack to
+       get around signal emission ordering problem.
+
+       * gtk/gtktreeselection.c (gtk_tree_selection_real_unselect_all):
+       fix to work with SINGLE 
+       (_gtk_tree_selection_internal_select_node): Major sanitization on
+       selections.  SINGLE now seems to work.
+
+       * tests/Makefile.am: add testtreecolumn.c:
+
+       * tests/testtreecolumn.c: New test.  Mostly points out selection
+       bugs currently, but will test columns later.
+
+       * gtk/gtkrbtree.c (_gtk_rbtree_remove_node): Fix really nasty
+       selection bug.  I hate touching this code -- it's scary.
+
 2001-02-26  Havoc Pennington  <hp@redhat.com>
 
        * gtk/testgtk.c: test the window state stuff
index 749c20c2d9d677b5c513e6f4621ccd9c30498cb3..fc423e44928deabda23311b83c54947b7c8ecbcf 100644 (file)
@@ -1,3 +1,25 @@
+Tue Feb 27 19:32:53 2001  Jonathan Blandford  <jrb@redhat.com>
+
+       * gtk/gtktreemodel.c (deleted_callback): Proxy out to
+       _gtk_tree_row_reference_deleted.
+       (inserted_callback): Proxy out to
+       _gtk_tree_row_reference_inserted.
+       (_gtk_tree_row_reference_new_from_view): Somewhat yukky hack to
+       get around signal emission ordering problem.
+
+       * gtk/gtktreeselection.c (gtk_tree_selection_real_unselect_all):
+       fix to work with SINGLE 
+       (_gtk_tree_selection_internal_select_node): Major sanitization on
+       selections.  SINGLE now seems to work.
+
+       * tests/Makefile.am: add testtreecolumn.c:
+
+       * tests/testtreecolumn.c: New test.  Mostly points out selection
+       bugs currently, but will test columns later.
+
+       * gtk/gtkrbtree.c (_gtk_rbtree_remove_node): Fix really nasty
+       selection bug.  I hate touching this code -- it's scary.
+
 2001-02-26  Havoc Pennington  <hp@redhat.com>
 
        * gtk/testgtk.c: test the window state stuff
index a37a728705a9e115bf60e046064a949a9b1d71a0..fc998bd3a9b8704ab93e9452cc81adcc8b00cafa 100644 (file)
@@ -705,7 +705,9 @@ gtk_cell_renderer_text_set_property (GObject      *object,
       {
         GdkColor color;
 
-        if (gdk_color_parse (g_value_get_string (value), &color))
+        if (!g_value_get_string (value))
+          set_bg_color (celltext, NULL);       /* reset to backgrounmd_set to FALSE */
+        else if (gdk_color_parse (g_value_get_string (value), &color))
           set_bg_color (celltext, &color);
         else
           g_warning ("Don't know color `%s'", g_value_get_string (value));
@@ -718,8 +720,10 @@ gtk_cell_renderer_text_set_property (GObject      *object,
       {
         GdkColor color;
 
-        if (gdk_color_parse (g_value_get_string (value), &color))
-          set_bg_color (celltext, &color);
+        if (!g_value_get_string (value))
+          set_fg_color (celltext, NULL);       /* reset to foreground_set to FALSE */
+        else if (gdk_color_parse (g_value_get_string (value), &color))
+          set_fg_color (celltext, &color);
         else
           g_warning ("Don't know color `%s'", g_value_get_string (value));
 
index d0eda95b2e15db5aa6d4e9a31e447e87cd795e61..53a13e29fa7ddf298dca1abebd8526a13ebbf731 100644 (file)
@@ -1009,7 +1009,6 @@ gtk_list_store_append (GtkListStore *list_store,
                       GtkTreeIter  *iter)
 {
   GtkTreePath *path;
-  gint i = 0;
 
   g_return_if_fail (list_store != NULL);
   g_return_if_fail (GTK_IS_LIST_STORE (list_store));
@@ -1030,7 +1029,7 @@ gtk_list_store_append (GtkListStore *list_store,
   validate_list_store (list_store);
   
   path = gtk_tree_path_new ();
-  gtk_tree_path_append_index (path, i);
+  gtk_tree_path_append_index (path, list_store->length - 1);
   gtk_tree_model_inserted (GTK_TREE_MODEL (list_store), path, iter);
   gtk_tree_path_free (path);
 }
index 2765599a5d8cd8d15089a231c8709781d08c4d7c..f4e7a1793636c03eda5f6a4aea75f94e1937886e 100644 (file)
@@ -914,7 +914,14 @@ _gtk_rbtree_remove_node (GtkRBTree *tree,
     tree->root = x;
 
   if (y != node)
-    node->children = y->children;
+    {
+      /* Copy the node over */
+      if (GTK_RBNODE_GET_COLOR (node) == GTK_RBNODE_BLACK)
+       node->flags = ((y->flags & (GTK_RBNODE_NON_COLORS)) | GTK_RBNODE_BLACK);
+      else
+       node->flags = ((y->flags & (GTK_RBNODE_NON_COLORS)) | GTK_RBNODE_RED);
+      node->children = y->children;
+    }
 
   if (GTK_RBNODE_GET_COLOR (y) == GTK_RBNODE_BLACK)
     _gtk_rbtree_remove_node_fixup (tree, x);
index eea9160b626492cbe6b11933a606396652c3afa9..8937b3200d7346ee04cbe983998f7ac9d9a86082 100644 (file)
@@ -32,8 +32,8 @@ typedef enum
   GTK_RBNODE_IS_PARENT = 1 << 2,
   GTK_RBNODE_IS_SELECTED = 1 << 3,
   GTK_RBNODE_IS_PRELIT = 1 << 4,
-  GTK_RBNODE_IS_VIEW = 1 << 5
-
+  GTK_RBNODE_IS_VIEW = 1 << 5,
+  GTK_RBNODE_NON_COLORS = GTK_RBNODE_IS_PARENT | GTK_RBNODE_IS_SELECTED | GTK_RBNODE_IS_PRELIT | GTK_RBNODE_IS_VIEW,
 } GtkRBNodeColor;
 
 typedef struct _GtkRBTree GtkRBTree;
index 8ad442dd7aa5fc53c83e17dff1c2c8b2a4137ab3..aa051f1155ddc7b0848bdb2d84ead84abdf1b63d 100644 (file)
@@ -516,6 +516,69 @@ struct _RowRefList
   GSList *list;
 };
 
+
+/*
+ * row_reference 
+ */
+void
+_gtk_tree_row_reference_inserted (GtkTreeRowReference *reference,
+                                 GtkTreePath         *path)
+{
+  if (reference->path)
+    {
+      gint depth = gtk_tree_path_get_depth (path);
+      gint ref_depth = gtk_tree_path_get_depth (reference->path);
+          
+      if (ref_depth >= depth)
+       {
+         gint *indices = gtk_tree_path_get_indices (path);
+         gint *ref_indices = gtk_tree_path_get_indices (reference->path);
+         gint i;
+
+         /* This is the depth that might affect us. */
+         i = depth - 1;
+              
+         if (indices[i] <= ref_indices[i])
+           ref_indices[i] += 1;
+       }
+    }
+}
+
+/* Returns TRUE if the reference path was deleted; FALSE otherwise */
+gboolean
+_gtk_tree_row_reference_deleted (GtkTreeRowReference *reference,
+                                GtkTreePath         *path)
+{
+  if (reference->path)
+    {
+      gint depth = gtk_tree_path_get_depth (path);
+      gint ref_depth = gtk_tree_path_get_depth (reference->path);
+
+      if (ref_depth >= depth)
+       {
+         /* Need to adjust path upward */
+         gint *indices = gtk_tree_path_get_indices (path);
+         gint *ref_indices = gtk_tree_path_get_indices (reference->path);
+         gint i;
+             
+         i = depth - 1;
+         if (indices[i] < ref_indices[i])
+           ref_indices[i] -= 1;
+         else if (indices[i] == ref_indices[i])
+           {
+             /* the referenced node itself, or its parent, was
+              * deleted, mark invalid
+              */
+
+             gtk_tree_path_free (reference->path);
+             reference->path = NULL;
+             return TRUE;
+           }
+       }
+    }
+  return FALSE;
+}
+
 static void
 release_row_references (gpointer data)
 {
@@ -562,28 +625,7 @@ inserted_callback (GtkTreeModel *tree_model,
     {
       GtkTreeRowReference *reference = tmp_list->data;
 
-      /* if reference->path == NULL then the reference was already
-       * deleted.
-       */
-      
-      if (reference->path)
-        {
-          gint depth = gtk_tree_path_get_depth (path);
-          gint ref_depth = gtk_tree_path_get_depth (reference->path);
-          
-          if (ref_depth >= depth)
-            {
-              gint *indices = gtk_tree_path_get_indices (path);
-              gint *ref_indices = gtk_tree_path_get_indices (reference->path);
-              gint i;
-
-              /* This is the depth that might affect us. */
-              i = depth - 1;
-              
-              if (indices[i] <= ref_indices[i])
-                ref_indices[i] += 1;
-            }
-        }
+      _gtk_tree_row_reference_inserted (reference, path);
 
       tmp_list = g_slist_next (tmp_list);
     }
@@ -614,36 +656,7 @@ deleted_callback (GtkTreeModel *tree_model,
     {
       GtkTreeRowReference *reference = tmp_list->data;
 
-      /* if reference->path == NULL then the reference was already
-       * deleted.
-       */
-      
-      if (reference->path)
-        {
-          gint depth = gtk_tree_path_get_depth (path);
-          gint ref_depth = gtk_tree_path_get_depth (reference->path);
-
-          if (ref_depth >= depth)
-            {
-              /* Need to adjust path upward */
-              gint *indices = gtk_tree_path_get_indices (path);
-              gint *ref_indices = gtk_tree_path_get_indices (reference->path);
-              gint i;
-
-              i = depth - 1;
-              if (indices[i] < ref_indices[i])
-                ref_indices[i] -= 1;
-              else if (indices[i] == ref_indices[i])
-                {
-                  /* the referenced node itself, or its parent, was
-                   * deleted, mark invalid
-                   */
-
-                  gtk_tree_path_free (reference->path);
-                  reference->path = NULL;
-                }
-            }
-        }
+      _gtk_tree_row_reference_deleted (reference, path);
 
       tmp_list = g_slist_next (tmp_list);
     }
@@ -673,7 +686,7 @@ connect_ref_callbacks (GtkTreeModel *model,
   /* FIXME */
   g_signal_connect_data (G_OBJECT (model),
                          "reordered",
-                         (GCallback) reorderedc_allback,
+                         (GCallback) reordered_callback,
                          refs,
                          NULL,
                          FALSE,
@@ -721,7 +734,20 @@ gtk_tree_row_reference_new (GtkTreeModel *model,
     }
   
   refs->list = g_slist_prepend (refs->list, reference);
+
+  return reference;
+}
+
+GtkTreeRowReference *
+_gtk_tree_row_reference_new_from_view (GtkTreePath *path)
+{
+  GtkTreeRowReference *reference;
   
+  reference = g_new (GtkTreeRowReference, 1);
+
+  reference->model = NULL;
+  reference->path = gtk_tree_path_copy (path);
+
   return reference;
 }
 
index 5e79d78fd0905e9a09fae28fa809cb323ab45977..74884b4f0773781243b769ec3de2af4e4ba571c0 100644 (file)
@@ -202,11 +202,19 @@ GtkTreePath *_gtk_tree_view_find_path                 (GtkTreeView       *tree_v
 void         _gtk_tree_view_update_size               (GtkTreeView       *tree_view);
 
 
+void _gtk_tree_view_column_set_tree_view (GtkTreeViewColumn *column,
+                                         GtkTreeView       *tree_view);
+
 GtkTreeSelection* _gtk_tree_selection_new                (void);
 GtkTreeSelection* _gtk_tree_selection_new_with_tree_view (GtkTreeView      *tree_view);
 void              _gtk_tree_selection_set_tree_view      (GtkTreeSelection *selection,
                                                           GtkTreeView      *tree_view);
 
+GtkTreeRowReference *_gtk_tree_row_reference_new_from_view (GtkTreePath *path);
+void                 _gtk_tree_row_reference_inserted      (GtkTreeRowReference *reference,
+                                                           GtkTreePath         *path);
+gboolean             _gtk_tree_row_reference_deleted       (GtkTreeRowReference *reference,
+                                                           GtkTreePath         *path);
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
index baf424a141b7dc5a58bf17d8b74d39cd1b62fd3e..a63fec367f4529e767895fc7761f2c41cbe7350e 100644 (file)
@@ -24,6 +24,8 @@
 
 static void gtk_tree_selection_init              (GtkTreeSelection      *selection);
 static void gtk_tree_selection_class_init        (GtkTreeSelectionClass *class);
+
+static void gtk_tree_selection_finalize          (GObject               *object);
 static gint gtk_tree_selection_real_select_all   (GtkTreeSelection      *selection);
 static gint gtk_tree_selection_real_unselect_all (GtkTreeSelection      *selection);
 static gint gtk_tree_selection_real_select_node  (GtkTreeSelection      *selection,
@@ -69,11 +71,12 @@ gtk_tree_selection_get_type (void)
 static void
 gtk_tree_selection_class_init (GtkTreeSelectionClass *class)
 {
-  GtkObjectClass *object_class;
+  GObjectClass *object_class;
 
-  object_class = (GtkObjectClass*) class;
+  object_class = (GObjectClass*) class;
   parent_class = g_type_class_peek_parent (class);
 
+  object_class->finalize = gtk_tree_selection_finalize;
   class->selection_changed = NULL;
 
   tree_selection_signals[SELECTION_CHANGED] =
@@ -91,6 +94,13 @@ gtk_tree_selection_init (GtkTreeSelection *selection)
   selection->type = GTK_TREE_SELECTION_SINGLE;
 }
 
+static void
+gtk_tree_selection_finalize (GObject *object)
+{
+  if (GTK_TREE_SELECTION (object)->destroy)
+    (* GTK_TREE_SELECTION (object)->destroy) (GTK_TREE_SELECTION (object)->user_data);
+}
+
 /**
  * _gtk_tree_selection_new:
  * 
@@ -214,6 +224,7 @@ gtk_tree_selection_set_mode (GtkTreeSelection     *selection,
  * @selection: A #GtkTreeSelection.
  * @func: The selection function.
  * @data: The selection function's data.
+ * @destroy: The destroy function for user data.  May be NULL.
  * 
  * Sets the selection function.  If set, this function is called before any node
  * is selected or unselected, giving some control over which nodes are selected.
@@ -221,7 +232,8 @@ gtk_tree_selection_set_mode (GtkTreeSelection     *selection,
 void
 gtk_tree_selection_set_select_function (GtkTreeSelection     *selection,
                                        GtkTreeSelectionFunc  func,
-                                       gpointer              data)
+                                       gpointer              data,
+                                       GtkDestroyNotify      destroy)
 {
   g_return_if_fail (selection != NULL);
   g_return_if_fail (GTK_IS_TREE_SELECTION (selection));
@@ -229,6 +241,7 @@ gtk_tree_selection_set_select_function (GtkTreeSelection     *selection,
 
   selection->user_func = func;
   selection->user_data = data;
+  selection->destroy = destroy;
 }
 
 /**
@@ -263,9 +276,10 @@ gtk_tree_selection_get_tree_view (GtkTreeSelection *selection)
  * @iter: The #GtkTreeIter, or NULL.
  * 
  * Sets @iter to the currently selected node if @selection is set to
- * #GTK_TREE_SELECTION_SINGLE.  Otherwise, it uses the anchor.  @iter may be
- * NULL if you just want to test if @selection has any selected nodes.  @model
- * is filled with the current model as a convenience.
+ * #GTK_TREE_SELECTION_SINGLE.  @iter may be NULL if you just want to test if
+ * @selection has any selected nodes.  @model is filled with the current model
+ * as a convenience.  This function will not work if you use @selection is
+ * #GTK_TREE_SELECTION_MULTI.
  * 
  * Return value: TRUE, if there is a selected node.
  **/
@@ -281,6 +295,9 @@ gtk_tree_selection_get_selected (GtkTreeSelection  *selection,
   
   g_return_val_if_fail (selection != NULL, FALSE);
   g_return_val_if_fail (GTK_IS_TREE_SELECTION (selection), FALSE);
+  g_return_val_if_fail (selection->type == GTK_TREE_SELECTION_SINGLE, FALSE);
+  g_return_val_if_fail (selection->tree_view != NULL, FALSE);
+  g_return_val_if_fail (selection->tree_view->priv->model != NULL, FALSE);
 
   if (model)
     *model = selection->tree_view->priv->model;
@@ -299,9 +316,6 @@ gtk_tree_selection_get_selected (GtkTreeSelection  *selection,
       return TRUE;
     }
 
-  g_return_val_if_fail (selection->tree_view != NULL, FALSE);
-  g_return_val_if_fail (selection->tree_view->priv->model != NULL, FALSE);
-
   retval = FALSE;
   
   if (!_gtk_tree_view_find_node (selection->tree_view,
@@ -713,8 +727,12 @@ gtk_tree_selection_real_unselect_all (GtkTreeSelection *selection)
       
       if (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_SELECTED))
        {
-         gtk_tree_selection_real_select_node (selection, tree, node, FALSE);
-         return TRUE;
+         if (gtk_tree_selection_real_select_node (selection, tree, node, FALSE))
+           {
+             gtk_tree_row_reference_free (selection->tree_view->priv->anchor);
+             selection->tree_view->priv->anchor = NULL;
+             return TRUE;
+           }
        }
       return FALSE;
     }
@@ -870,8 +888,8 @@ gtk_tree_selection_select_range (GtkTreeSelection *selection,
   if (gtk_tree_selection_real_select_range (selection, start_path, end_path))
     gtk_signal_emit (GTK_OBJECT (selection), tree_selection_signals[SELECTION_CHANGED]);
 }
+
 /* Called internally by gtktreeview.c It handles actually selecting the tree.
- * This should almost certainly ever be called by anywhere else.
  */
 void
 _gtk_tree_selection_internal_select_node (GtkTreeSelection *selection,
@@ -884,62 +902,103 @@ _gtk_tree_selection_internal_select_node (GtkTreeSelection *selection,
   gint dirty = FALSE;
   GtkTreePath *anchor_path = NULL;
 
+
   if (selection->tree_view->priv->anchor)
     anchor_path = gtk_tree_row_reference_get_path (selection->tree_view->priv->anchor);
 
-  if (((state & GDK_SHIFT_MASK) == GDK_SHIFT_MASK) && (anchor_path == NULL))
-    {
-      if (selection->tree_view->priv->anchor)
-        gtk_tree_row_reference_free (selection->tree_view->priv->anchor);
-      
-      selection->tree_view->priv->anchor =
-        gtk_tree_row_reference_new (selection->tree_view->priv->model,
-                                    path);
-      dirty = gtk_tree_selection_real_select_node (selection, tree, node, TRUE);
-    }
-  else if ((state & (GDK_CONTROL_MASK|GDK_SHIFT_MASK)) == (GDK_SHIFT_MASK|GDK_CONTROL_MASK))
+  if (selection->type == GTK_TREE_SELECTION_SINGLE)
     {
-      gtk_tree_selection_select_range (selection,
-                                       anchor_path,
-                                      path);
+      /* Did we try to select the same node again? */
+      if (anchor_path && gtk_tree_path_compare (path, anchor_path) == 0)
+       {
+         if ((state & GDK_CONTROL_MASK) == GDK_CONTROL_MASK)
+           {
+             dirty = gtk_tree_selection_real_unselect_all (selection);
+           }
+       }
+      else
+       {
+         /* FIXME: We only want to select the new node if we can unselect the
+          * old one, and we can select the new one.  We are currently
+          * unselecting the old one first, then trying the new one. */
+         if (anchor_path)
+           {
+             dirty = gtk_tree_selection_real_unselect_all (selection);
+             if (dirty)
+               {
+                 if (selection->tree_view->priv->anchor)
+                   gtk_tree_row_reference_free (selection->tree_view->priv->anchor);
+                 if (gtk_tree_selection_real_select_node (selection, tree, node, TRUE))
+                   {
+                     selection->tree_view->priv->anchor =
+                       gtk_tree_row_reference_new (selection->tree_view->priv->model, path);
+                   }
+               }
+           }
+         else
+           {
+             if (gtk_tree_selection_real_select_node (selection, tree, node, TRUE))
+               {
+                 dirty = TRUE;
+                 selection->tree_view->priv->anchor =
+                   gtk_tree_row_reference_new (selection->tree_view->priv->model, path);
+               }
+           }
+       }
     }
-  else if ((state & GDK_CONTROL_MASK) == GDK_CONTROL_MASK)
+  else if (selection->type == GTK_TREE_SELECTION_MULTI)
     {
-      flags = node->flags;
-      if (selection->type == GTK_TREE_SELECTION_SINGLE)
-       dirty = gtk_tree_selection_real_unselect_all (selection);
-
-      if (selection->tree_view->priv->anchor)
-        gtk_tree_row_reference_free (selection->tree_view->priv->anchor);
+      if (((state & GDK_SHIFT_MASK) == GDK_SHIFT_MASK) && (anchor_path == NULL))
+       {
+         if (selection->tree_view->priv->anchor)
+           gtk_tree_row_reference_free (selection->tree_view->priv->anchor);
       
-      selection->tree_view->priv->anchor =
-        gtk_tree_row_reference_new (selection->tree_view->priv->model,
-                                    path);      
+         selection->tree_view->priv->anchor =
+           gtk_tree_row_reference_new (selection->tree_view->priv->model,
+                                       path);
+         dirty = gtk_tree_selection_real_select_node (selection, tree, node, TRUE);
+       }
+      else if ((state & (GDK_CONTROL_MASK|GDK_SHIFT_MASK)) == (GDK_SHIFT_MASK|GDK_CONTROL_MASK))
+       {
+         gtk_tree_selection_select_range (selection,
+                                          anchor_path,
+                                          path);
+       }
+      else if ((state & GDK_CONTROL_MASK) == GDK_CONTROL_MASK)
+       {
+         flags = node->flags;
+         if (selection->tree_view->priv->anchor)
+           gtk_tree_row_reference_free (selection->tree_view->priv->anchor);
+      
+         selection->tree_view->priv->anchor =
+           gtk_tree_row_reference_new (selection->tree_view->priv->model,
+                                       path);      
 
-      if ((flags & GTK_RBNODE_IS_SELECTED) == GTK_RBNODE_IS_SELECTED)
-       dirty |= gtk_tree_selection_real_select_node (selection, tree, node, FALSE);
+         if ((flags & GTK_RBNODE_IS_SELECTED) == GTK_RBNODE_IS_SELECTED)
+           dirty |= gtk_tree_selection_real_select_node (selection, tree, node, FALSE);
+         else
+           dirty |= gtk_tree_selection_real_select_node (selection, tree, node, TRUE);
+       }
+      else if ((state & GDK_SHIFT_MASK) == GDK_SHIFT_MASK)
+       {
+         dirty = gtk_tree_selection_real_unselect_all (selection);
+         dirty |= gtk_tree_selection_real_select_range (selection,
+                                                        anchor_path,
+                                                        path);
+       }
       else
-       dirty |= gtk_tree_selection_real_select_node (selection, tree, node, TRUE);
-    }
-  else if ((state & GDK_SHIFT_MASK) == GDK_SHIFT_MASK)
-    {
-      dirty = gtk_tree_selection_real_unselect_all (selection);
-      dirty |= gtk_tree_selection_real_select_range (selection,
-                                                     anchor_path,
-                                                    path);
-    }
-  else
-    {
-      dirty = gtk_tree_selection_real_unselect_all (selection);
+       {
+         dirty = gtk_tree_selection_real_unselect_all (selection);
 
-      if (selection->tree_view->priv->anchor)
-        gtk_tree_row_reference_free (selection->tree_view->priv->anchor);
+         if (selection->tree_view->priv->anchor)
+           gtk_tree_row_reference_free (selection->tree_view->priv->anchor);
       
-      selection->tree_view->priv->anchor =
-        gtk_tree_row_reference_new (selection->tree_view->priv->model,
-                                    path);
+         selection->tree_view->priv->anchor =
+           gtk_tree_row_reference_new (selection->tree_view->priv->model,
+                                       path);
       
-      dirty |= gtk_tree_selection_real_select_node (selection, tree, node, TRUE);
+         dirty |= gtk_tree_selection_real_select_node (selection, tree, node, TRUE);
+       }
     }
 
   if (anchor_path)
index ddbc91e26522602479ed19b165e13ca3dd44fee9..9478872ca10feea711a3f5a92db9229739a0fb88 100644 (file)
@@ -58,6 +58,7 @@ struct _GtkTreeSelection
   GtkTreeSelectionMode type;
   GtkTreeSelectionFunc user_func;
   gpointer user_data;
+  GtkDestroyNotify destroy;
 };
 
 struct _GtkTreeSelectionClass
@@ -74,7 +75,8 @@ void             gtk_tree_selection_set_mode            (GtkTreeSelection
                                                         GtkTreeSelectionMode         type);
 void             gtk_tree_selection_set_select_function (GtkTreeSelection            *selection,
                                                         GtkTreeSelectionFunc         func,
-                                                        gpointer                     data);
+                                                        gpointer                     data,
+                                                        GtkDestroyNotify             destroy);
 gpointer         gtk_tree_selection_get_user_data       (GtkTreeSelection            *selection);
 GtkTreeView*     gtk_tree_selection_get_tree_view       (GtkTreeSelection            *selection);
 
index 1c7ceb1a8f07ab7b1563ca8e90e268315970b46c..3f3c5bfb1f9a6c7ad3752920599901e2d55df1fa 100644 (file)
@@ -2742,7 +2742,8 @@ gtk_tree_view_deleted (GtkTreeModel *model,
 
   g_assert (tree_view->priv->prelight_node == NULL);
   
-  if (tree->root->count == 1)
+  if ((tree->root->count == 1) &&
+      (tree_view->priv->tree != tree))
     {
       _gtk_rbtree_remove (tree);
     }
@@ -3438,7 +3439,10 @@ _gtk_tree_view_update_size (GtkTreeView *tree_view)
       width += TREE_VIEW_COLUMN_WIDTH (column);
     }
 
-  height = tree_view->priv->tree->root->offset + TREE_VIEW_VERTICAL_SEPARATOR;
+  if (tree_view->priv->tree == NULL)
+    height = 0;
+  else
+    height = tree_view->priv->tree->root->offset + TREE_VIEW_VERTICAL_SEPARATOR;
 
   if (tree_view->priv->width != width)
     {
@@ -4416,6 +4420,13 @@ gtk_tree_view_get_background_xrange (GtkTreeView       *tree_view,
     }
 }
 
+void
+_gtk_tree_view_column_set_tree_view (GtkTreeViewColumn *column,
+                                    GtkTreeView       *tree_view)
+{
+  column->tree_view = tree_view;
+}
+
 static void
 gtk_tree_view_get_cell_xrange (GtkTreeView       *tree_view,
                                GtkRBTree         *tree,
index 1c39a38268a8582cd8bd3ae07ea8457c8ff57df0..116d4f56aa09ae99f670ca7829d94e6841fb8846 100644 (file)
@@ -31,10 +31,17 @@ LDADDS = @STRIP_BEGIN@                                      \
 @STRIP_END@
 
 noinst_PROGRAMS =              \
-       testtreeview
+       testtreeview            \
+       testtreecolumns
 
 testtreeview_DEPENDENCIES = $(DEPS)
 
 testtreeview_LDADD = $(LDADDS)
 
 testtreeview_SOURCES = testtreeview.c
+
+testtreecolumns_DEPENDENCIES = $(DEPS)
+
+testtreecolumns_LDADD = $(LDADDS)
+
+testtreecolumns_SOURCES = testtreecolumns.c
diff --git a/tests/testtreecolumns.c b/tests/testtreecolumns.c
new file mode 100644 (file)
index 0000000..8be6e1b
--- /dev/null
@@ -0,0 +1,127 @@
+#include <gtk/gtk.h>
+
+GtkWidget *left_tree_view;
+GtkWidget *right_tree_view;
+GtkTreeModel *left_tree_model;
+GtkTreeModel *right_tree_model;
+
+static void
+add_clicked (GtkWidget *button, gpointer data)
+{
+  GtkTreeIter iter;
+  GtkTreeViewColumn *column;
+  static gint i = 0;
+
+  gchar *label = g_strdup_printf ("Column %d", i);
+  column = gtk_tree_view_column_new ();
+  gtk_list_store_append (GTK_LIST_STORE (left_tree_model), &iter);
+  gtk_list_store_set (GTK_LIST_STORE (left_tree_model), &iter, 0, label, 1, column, -1);
+  g_free (label);
+  i++;
+}
+
+static void
+add_left_clicked (GtkWidget *button, gpointer data)
+{
+
+}
+
+
+static void
+add_right_clicked (GtkWidget *button, gpointer data)
+{
+  GtkTreeIter iter;
+  gchar *label;
+  GtkTreeViewColumn *column;
+
+  GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (left_tree_view));
+
+  gtk_tree_selection_get_selected (selection, NULL, &iter);
+  gtk_tree_model_get (GTK_TREE_MODEL (left_tree_model),
+                     &iter, 0, &label, 1, &column, -1);
+  gtk_list_store_remove (GTK_LIST_STORE (left_tree_model), &iter);
+
+  gtk_list_store_append (GTK_LIST_STORE (right_tree_model), &iter);
+  gtk_list_store_set (GTK_LIST_STORE (right_tree_model), &iter, 0, label, 1, column, -1);
+  g_free (label);
+}
+
+static void
+selection_changed (GtkTreeSelection *selection, GtkWidget *button)
+{
+  if (gtk_tree_selection_get_selected (selection, NULL, NULL))
+    gtk_widget_set_sensitive (button, TRUE);
+  else
+    gtk_widget_set_sensitive (button, FALSE);
+}
+
+int
+main (int argc, char *argv[])
+{
+  GtkWidget *window;
+  GtkWidget *hbox, *vbox, *bbox;
+  GtkWidget *button;
+  GtkTreeViewColumn *column;
+  GtkCellRenderer *cell;
+  GtkWidget *swindow;
+
+  gtk_init (&argc, &argv);
+
+  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  gtk_window_set_default_size (GTK_WINDOW (window), 500, 300);
+  vbox = gtk_vbox_new (FALSE, 8);
+  gtk_container_set_border_width (GTK_CONTAINER (vbox), 8);
+  gtk_container_add (GTK_CONTAINER (window), vbox);
+
+  hbox = gtk_hbox_new (FALSE, 8);
+  gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
+
+  cell = gtk_cell_renderer_text_new ();
+  g_object_set (G_OBJECT (cell), "foreground", "black", NULL);
+  left_tree_model = (GtkTreeModel *) gtk_list_store_new_with_types (2, G_TYPE_STRING, GTK_TYPE_POINTER);
+  swindow = gtk_scrolled_window_new (NULL, NULL);
+  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swindow), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+  left_tree_view = gtk_tree_view_new_with_model (left_tree_model);
+  gtk_container_add (GTK_CONTAINER (swindow), left_tree_view);
+  column = gtk_tree_view_column_new_with_attributes ("Unattached Columns", cell, "text", 0, NULL);
+  gtk_tree_view_append_column (GTK_TREE_VIEW (left_tree_view), column);
+  gtk_box_pack_start (GTK_BOX (hbox), swindow, TRUE, TRUE, 0);
+
+  bbox = gtk_vbutton_box_new ();
+  gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_SPREAD);
+  gtk_button_box_set_child_size (GTK_BUTTON_BOX (bbox), 0, 0);
+  gtk_box_pack_start (GTK_BOX (hbox), bbox, FALSE, FALSE, 0);
+
+  button = gtk_button_new_with_label ("<<");
+  gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (add_left_clicked), NULL);
+  gtk_box_pack_start (GTK_BOX (bbox), button, FALSE, FALSE, 0);
+
+  button = gtk_button_new_with_label (">>");
+  gtk_widget_set_sensitive (button, FALSE);
+  gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (add_right_clicked), NULL);
+  gtk_signal_connect (GTK_OBJECT (gtk_tree_view_get_selection (GTK_TREE_VIEW (left_tree_view))),
+                     "selection-changed", GTK_SIGNAL_FUNC (selection_changed), button);
+  gtk_box_pack_start (GTK_BOX (bbox), button, FALSE, FALSE, 0);
+
+  swindow = gtk_scrolled_window_new (NULL, NULL);
+  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swindow), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+  right_tree_model = (GtkTreeModel *) gtk_list_store_new_with_types (2, G_TYPE_STRING, GTK_TYPE_POINTER);
+  right_tree_view = gtk_tree_view_new_with_model (right_tree_model);
+  column = gtk_tree_view_column_new_with_attributes ("Unattached Columns", cell, "text", 0, NULL);
+  gtk_tree_view_append_column (GTK_TREE_VIEW (right_tree_view), column);
+  gtk_container_add (GTK_CONTAINER (swindow), right_tree_view);
+  gtk_box_pack_start (GTK_BOX (hbox), swindow, TRUE, TRUE, 0);
+
+  gtk_box_pack_start (GTK_BOX (vbox), gtk_hseparator_new (), FALSE, FALSE, 0);
+
+  hbox = gtk_hbox_new (FALSE, 8);
+  gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
+  button = gtk_button_new_with_label ("Add new Column");
+  gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (add_clicked), left_tree_model);
+  gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
+
+  gtk_widget_show_all (window);
+  gtk_main ();
+
+  return 0;
+}